package com.hundsun.documentripper.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName StringUtil
 * @Author Lonely_man
 * @Date 2020/11/20 22:13
 * @Version 1.0
 **/
public class StringUtil {
    private final static Pattern DYNAMIC_PATTERN = Pattern.compile("@\\d+\\s+");

    private final static Pattern HTTP_PATTERN = Pattern.compile("(http|ftp|https):\\/\\/([\\w.]+\\/?)\\S*");

    private final static Pattern NUMBER_PATTERN = Pattern.compile("[0-9]*");

    public static String addPrefix(int num, String prefix, int length) {
        return String.format("%04d", num);
    }

    public static boolean isStringAvaliable(String string) {
        return string != null && !"".equals(string.trim());
    }

    /**
     * 字符串首字母小写
     *
     * @param name
     * @return
     */
    public static String lowerFirstLetter(String name) {
        if (name != null && name.trim().length() != 0) {
            {
                return name.substring(0, 1).toLowerCase() + name.substring(1);
            }
        }
        return null;
    }

    /**
     * 判断当前字符串是否为NUll或空格
     *
     * @param str
     * @return
     */
    public static boolean isNull(String str) {
        return str == null || str.trim().length() == 0;
    }

    /**
     * 判断当前字符串是否为空格或空字符串
     */

    public static Boolean isEmptyStr(String str) {
        return str != null && str.trim().length() == 0;
    }

    /**
     * 判断当前字符串是否不为NUll或空格
     *
     * @param str
     * @return
     */
    public static boolean isNotNull(String str) {
        return str != null && str.trim().length() != 0;
    }

    /**
     * 判断当前字符串是否为NUll或空格
     *
     * @param obj
     * @return
     */
    public static boolean isNull(Object obj) {
        return null == obj;
    }

    /**
     * 判断当前字符串是否不为NUll或空格
     *
     * @param obj
     * @return
     */
    public static boolean isNotNull(Object obj) {
        return !isNull(obj);
    }

    /**
     * 判断字符串是否【为空】
     *
     * @param str 被判断的字符串参数
     * @return boolean
     */
    public static boolean isEmpty(String str) {
        return null == str || 0 == str.length();
    }

    /**
     * 判断字符串是否【不为空】
     *
     * @param str 被判断的字符串
     * @return boolean
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 判断字符串数组是否为空
     *
     * @param arr 需要判断数组
     * @return boolean
     */
    public static boolean isEmpty(String[] arr) {
        return null == arr || 0 == arr.length;
    }

    /**
     * 判断字符串数组是否不为空
     *
     * @param arr 需要判断数组
     * @return boolean
     */
    public static boolean isNotEmpty(String[] arr) {
        return !isEmpty(arr);
    }

    /**
     * 判断Collection是否为空
     *
     * @return boolean
     */
    public static <T> boolean isEmpty(Collection<T> list) {
        return null == list || 0 == list.size();
    }

    /**
     * 判断Collection是否不为空
     *
     * @param list 需要判断集合
     * @return boolean
     */
    public static <T> boolean isNotEmpty(Collection<T> list) {
        return !isEmpty(list);
    }

    /**
     * 检查字符串是否是空白：<code>null</code>、空字符串<code>""</code>或只有空白字符。
     * <p>
     * <per>
     * StringUtil.isBlank(null) = true
     * StringUtil.isBlank("") = true
     * StringUtil.isBlank(" ") = true
     * StringUtil.isBlank("bob") = false
     * StringUtil.isBlank("  bob  ") = false
     * </per>
     *
     * @param str 要检查的字符串
     * @return 如果为空白, 则返回<code>true</code>
     */
    public static boolean isBlank(String str) {
        int length;

        if ((str == null) || ((length = str.length()) == 0)) {
            return true;
        }

        for (int i = 0; i < length; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查字符串是否不是空白：<code>null</code>、空字符串<code>""</code>或只有空白字符。
     * <p>
     * <per>
     * StringUtil.isBlank(null) = false
     * StringUtil.isBlank("") = false
     * StringUtil.isBlank(" ") = false
     * StringUtil.isBlank("bob") = true
     * StringUtil.isBlank("  bob  ") = true
     * </per>
     *
     * @param str 要检查的字符串
     * @return 如果为空白, 则返回<code>true</code>
     */
    public static boolean isNotBlank(String str) {
        int length;

        if ((str == null) || ((length = str.length()) == 0)) {
            return false;
        }

        for (int i = 0; i < length; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断链接是否以http开头的
     *
     * @param link
     * @return
     */
    public static boolean isHttpAvaliable(String link) {
        Matcher matcher = HTTP_PATTERN.matcher(link);
        if (!matcher.find()) {
            return false;
        }
        return true;
    }

    /**
     * 将字符串转换为整形
     *
     * @param str
     * @return
     */
    public static int toInt(final String str) {
        return toInt(str, 0);
    }

    /**
     * 将字符串转换为整形
     *
     * @param str
     * @param i
     * @return
     */
    public static int toInt(final String str, final int i) {
        int result = 0;

        try {
            result = Integer.parseInt(str);
        } catch (NumberFormatException e) {
            result = i;
        }
        return result;
    }

    /**
     * 将字符串转换为整形
     *
     * @param str
     * @return
     */
    public static Integer toInteger(final String str) {
        Integer o = null;
        if (str == null) {
            {
                return null;
            }
        }
        try {
            o = Integer.valueOf(str.trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

    /**
     * 将字符串转换为整形
     *
     * @param str
     * @return
     */
    public static Long toLong(final String str) {
        Long o = null;
        if (str == null) {
            return null;
        }
        try {
            o = Long.valueOf(str.trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

    /**
     * 将字符串转换为整形
     *
     * @param str
     * @param default_val 默认值
     * @return
     */
    public static Long toLong(final String str, Long default_val) {
        Long o = toLong(str);
        if (null == o) {
            o = default_val;
        }
        return o;
    }

    /**
     * 将对象转换成String
     * 判断非空
     *
     * @param obj
     * @return String
     * @Title: obj2str
     */
    public static String obj2str(Object obj) {
        if (null == obj) {
            return "";
        }
        return obj.toString();
    }

    /**
     *
     */
    /**
     * 删除input字符串中的html格式
     *
     * @param input
     * @param length
     * @return
     */
    public static String splitAndFilterString(String input, int length) {
        if (input == null || "".equals(input.trim())) {
            return "";
        }
        // 去掉所有html元素,
        String str = input.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll(
                "<[^>]*>", "");
        str = str.replaceAll("[(/>)<]", "");
        int len = str.length();
        if (len <= length) {
            return str;
        } else {
            str = str.substring(0, length);
            str += "......";
        }
        return str;
    }

    /**
     * 去掉字符串的html代码
     *
     * @param htmlStr 字符串
     * @return 结果
     */
    public static String htmlToStr(String htmlStr) {
        StringBuilder result = new StringBuilder();
        boolean flag = true;
        if (htmlStr == null) {
            return null;
        }
        char[] a = htmlStr.toCharArray();
        int length = a.length;
        for (int i = 0; i < length; i++) {
            if (a[i] == '<') {
                flag = false;
                continue;
            }
            if (a[i] == '>') {
                flag = true;
                continue;
            }
            if (flag == true) {
                result.append(a[i]);
            }
        }
        return result.toString();
    }

    /**
     * 字符串按字节截取
     *
     * @param text   原字符
     * @param length 截取长度
     * @return String
     */

    public static String splitString(String text, int length) {
        return splitString(text, length, "...");

    }

    /**
     * 字符串按字节截取
     *
     * @param text    原字符
     * @param length  截取长度
     * @param endWith 替代符
     * @return String
     */

    public static String splitString(String text, int length, String endWith) {
        if (text == null || "".equals(text)) {
            return "";
        }
        if (length <= 0) {
            return "";
        }
        int textLength = text.length();
        int byteLength = 0;
        StringBuffer returnStr = new StringBuffer();
        String returnString = "";
        try {
            for (int i = 0; i < textLength && byteLength < length * 2; i++) {
                String str_i = text.substring(i, i + 1);
                if (str_i.getBytes("UTF-8").length == 1) {// 英文
                    byteLength++;
                } else {// 中文
                    byteLength += 2;
                }
                returnStr.append(str_i);
            }
            if (byteLength < text.getBytes("GBK").length) {// getBytes("GBK")每个汉字长2，getBytes("UTF-8")每个汉字长度为3
                returnStr.append(endWith);
            }

            returnString = returnStr.toString();
            /*if (returnString.getBytes("GBK").length % 2 == 1) { // 存在单数英文字符少截取一个字，避免显示错位。例如:“KHS单车生活馆”截取4个汉字时
                returnString = returnString.substring(0,
						returnString.length() - 1);
			}*/
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return returnString;

    }

    public static String leftTime(Date RegistrationDeadline)
            throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String systemTime = sdf.format(new Date()).toString();
        Date sysTime = sdf.parse(systemTime);
        // 将截取到的时间字符串转化为时间格式的字符串
        Date beginTime = RegistrationDeadline;
        String bgTime = sdf.format(beginTime).toString();
        Date bgeTime = sdf.parse(bgTime);
        // 默认为毫秒，除以1000是为了转换成秒
        long interval = (bgeTime.getTime() - sysTime.getTime()) / 1000;// 秒
        long day = interval / (24 * 3600);// 天
        long hour = interval % (24 * 3600) / 3600;// 小时
        long minute = interval % 3600 / 60;// 分钟
        if (interval < 0) {
            return "";
        }
        return "还有" + day + "天" + hour + "小时" + minute + "分";
    }

    /***
     * 抽取在动态内容中@id的userId
     *
     * @param content
     * @return
     */
    public static List<String> getUserIdsFromContent(String content) {
        if (content == null || content.trim().length() == 0) {
            return null;
        }
        Matcher mc = DYNAMIC_PATTERN.matcher(content);
        List<String> ids = new ArrayList<String>();
        while (mc.find()) {
            String userUrl = mc.group();
            String userId = userUrl.substring(1).trim();
            if (!ids.contains(userId)) {
                ids.add(userId);
            }
        }
        return ids;
    }

    /**
     * 判断字符串是否为数字
     */
    public static boolean isNumeric(String str) {
        return NUMBER_PATTERN.matcher(str).matches();
    }

    /**
     * 判断字符串非空，为空返回空字符串，否则返回trim的值
     *
     * @param str
     * @return String
     * @Title: val
     * @Description: TODO
     */
    public static String val(String str) {
        return null == str ? "" : str.trim();
    }

    /**
     * 对象转换map对象
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }

        Map<String, Object> map = new HashMap<String, Object>();

        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();
            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = getter != null ? getter.invoke(obj) : null;
            map.put(key, value);
        }

        return map;
    }

    /**
     * @Description:把list转换为一个用逗号分隔的字符串
     */
    public static String listToString(@SuppressWarnings("rawtypes") List list) {
        StringBuilder sb = new StringBuilder();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (i < list.size() - 1) {
                    sb.append(list.get(i) + ",");
                } else {
                    sb.append(list.get(i));
                }
            }
        }
        return sb.toString();
    }

    /**
     * @Description:把数组转换为一个用逗号分隔的字符串 ，以便于用in+String 查询
     */
    public static String converToString(String[] ig) {
        StringBuffer strbuff = new StringBuffer();
        if (ig != null && ig.length > 0) {
            for (int i = 0; i < ig.length; i++) {
                strbuff.append(ig[i]).append(",");
            }
        }
        String str = strbuff.substring(0, strbuff.length() - 1);
        return str;
    }

    /**
     * 判断字符串是否【为空】
     *
     * @param <T>
     * @param str 被判断的字符串参数
     * @return boolean
     */
    public static <T> boolean isEmpty(T[] list) {
        return null == list || 0 == list.length;
    }

    /**
     * 判断字符串是否【不为空】
     *
     * @param <T>
     * @param str 被判断的字符串
     * @return boolean
     */
    public static <T> boolean isNotEmpty(T[] list) {
        return !isEmpty(list);
    }

    /**
     * 对pojo对象所有{@code java.lang.String}类型属性去除前后空格（该属性必须同时拥有getter和setter才能被执行此操作）
     *
     * @param pojo
     * @author lizhensi
     * @createtime 2010-12-23 上午10:21:08
     */
    public static void trim(Object pojo) {
        Field[] fields = pojo.getClass().getDeclaredFields();
        for (Field f : fields) {
            if (f.getType() == String.class) {
                String fName = f.getName();
                String pojoGetSet = fName.substring(0, 1).toUpperCase()
                        + fName.substring(1, fName.length());
                try {
                    Method getter = pojo.getClass().getMethod(
                            "get" + pojoGetSet);
                    Method setter = pojo.getClass().getMethod(
                            "set" + pojoGetSet, String.class);

                    Object value = getter.invoke(pojo);
                    if (value != null) {
                        setter.invoke(pojo, StringUtil.trim(value.toString()));
                    }
                } catch (SecurityException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            }
        }
    }

    /**
     * 对pojo对象所有{@code java.lang.String}类型属性去除前后空格（该属性必须同时拥有getter和setter才能被执行此操作）
     *
     * @param pojo
     * @param exceptFields 不执行该操作的属性名
     * @author lizhensi
     * @createtime 2010-12-23 上午10:24:24
     */
    public static void trim(Object pojo, String[] exceptFields) {
        Set<String> exceptFieldSet = new HashSet<String>(exceptFields.length);
        for (String f : exceptFields) {
            exceptFieldSet.add(f);
        }

        Field[] fields = pojo.getClass().getDeclaredFields();
        for (Field f : fields) {
            if (f.getType() == String.class) {
                String fName = f.getName();
                if (exceptFieldSet.contains(fName)) {
                    continue;
                }
                String pojoGetSet = fName.substring(0, 1).toUpperCase()
                        + fName.substring(1, fName.length());
                try {
                    Method getter = pojo.getClass().getMethod(
                            "get" + pojoGetSet);
                    Method setter = pojo.getClass().getMethod(
                            "set" + pojoGetSet, String.class);

                    Object value = getter.invoke(pojo);
                    if (value != null) {
                        setter.invoke(pojo, StringUtil.trim(value.toString()));
                    }
                } catch (SecurityException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            }
        }
    }

    /**
     * 除去字符串头尾部的空白，如果字符串是<code>null</code>，依然返回<code>null</code>。
     * <p>
     * <p>
     * 注意，和<code>String.trim</code>不同，此方法使用<code>Character.isWhitespace</code>来判定空白，
     * 因而可以除去英文字符集之外的其它空白，如中文空格。
     * <per>
     * StringUtil.trim(null)          = null
     * StringUtil.trim("")            = ""
     * StringUtil.trim("     ")       = ""
     * StringUtil.trim("abc")         = "abc"
     * StringUtil.trim("    abc    ") = "abc"
     * </per>
     * </p>
     *
     * @param str 要处理的字符串
     * @return 除去空白的字符串，如果原字串为<code>null</code>，则返回<code>null</code>
     */
    public static String trim(String str) {
        return trim(str, null, 0);
    }

    /**
     * 除去字符串头尾部的指定字符，如果字符串是<code>null</code>，依然返回<code>null</code>。
     * <per>
     * StringUtil.trim(null, *)          = null
     * StringUtil.trim("", *)            = ""
     * StringUtil.trim("abc", null)      = "abc"
     * StringUtil.trim("  abc", null)    = "abc"
     * StringUtil.trim("abc  ", null)    = "abc"
     * StringUtil.trim(" abc ", null)    = "abc"
     * StringUtil.trim("  abcyx", "xyz") = "  abc"
     * </per>
     *
     * @param str        要处理的字符串
     * @param stripChars 要除去的字符，如果为<code>null</code>表示除去空白字符
     * @param mode       <code>-1</code>表示trimStart，<code>0</code>表示trim全部，<code>1</code>表示trimEnd
     * @return 除去指定字符后的的字符串，如果原字串为<code>null</code>，则返回<code>null</code>
     */
    private static String trim(String str, String stripChars, int mode) {
        if (str == null) {
            return null;
        }

        int length = str.length();
        int start = 0;
        int end = length;

        // 扫描字符串头部
        if (mode <= 0) {
            if (stripChars == null) {
                while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
                    start++;
                }
            } else if (stripChars.length() == 0) {
                return str;
            } else {
                while ((start < end) && (stripChars.indexOf(str.charAt(start)) != -1)) {
                    start++;
                }
            }
        }

        // 扫描字符串尾部
        if (mode >= 0) {
            if (stripChars == null) {
                while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
                    end--;
                }
            } else if (stripChars.length() == 0) {
                return str;
            } else {
                while ((start < end) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
                    end--;
                }
            }
        }

        if ((start > 0) || (end < length)) {
            return str.substring(start, end);
        }

        return str;
    }

    /**
     * 判断字符串是否能转换为BigDecimal
     *
     * @param str
     * @return
     */
    public static boolean isNum(String str) {
        try {
            new BigDecimal(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 特定字符截取
     *
     * @param str
     * @param character
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String isSci(String val) {
        Stack st = new Stack();
        String str = "";
        for (char ch : val.toCharArray()) {
            if (ch != ']') {
                st.push(ch);
            } else {
                while (true) {
                    char tmp = (Character) st.pop();
                    if (tmp == '[') {
                        break;
                    }
                    str = tmp + str;
                }
            }
        }
        return StringUtil.trim(str);
    }

    /**
     * 判断两个字符串数组是否相等
     *
     * @param val1
     * @param val2
     * @return
     */
    public static boolean isEqualLength(String[] val1, String[] val2) {
        int i1 = val1.length;
        int i2 = val2.length;
        if (i1 == i2) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 字符串替换
     *
     * @param val
     * @param replace
     * @return
     */
    public static String getReplace(String val, String replace) {
        try {
            if (isEmpty(val) || isEmpty(replace)) {
                return "";
            }
            return val.replace(",", replace);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 截取字符串
     *
     * @param val
     * @param i
     * @return
     */
    public static String couOut(String val, int i) {
        try {
            if (isEmpty(val)) {
                return "";
            }
            return val.substring(i, val.length());
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 根据起始值、结束值来计算
     *
     * @param startNum 大于等于开始编号
     * @param endNum   小于等于结束编号
     * @param length   补齐的编号位数
     * @return List<String>
     * @Title: supplyNum
     */
    public static List<String> supplyNum(String linkString, long startNum, long endNum, int length) {
        List<String> nos = new ArrayList<String>();
        // 拼接记录
        for (long i = startNum; i <= endNum; i++) {
            String str = Long.toString(i);
            nos.add(supplyNum(linkString, str, length));
        }
        // 返回编号
        return nos;
    }

    /**
     * 字符串合并
     *
     * @param set
     * @return String
     * @Title: join
     */
    public static String supplyNum(String linkString, String str, int num) {
        String zeros = "0000";
        if (str.length() > num) {
            return linkString + str.substring(0, num);
        } else {
            return linkString + zeros.substring(0, num - str.length()) + str;
        }
    }

    /**
     * 获取随机字符串
     * @param length 字符串的长度
     * @return 随机的字符串
     */
    public static String getRandomStr(int length){
        //产生随机数
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        //循环length次
        for(int i=0; i<length; i++){
            //产生0-2个随机数，既与a-z，A-Z，0-9三种可能
            int number=random.nextInt(3);
            long result=0;
            switch(number){
                //如果number产生的是数字0；
                case 0:
                    //产生A-Z的ASCII码
                    result=Math.round(Math.random()*25+65);
                    //将ASCII码转换成字符
                    sb.append(String.valueOf((char)result));
                    break;
                case 1:
                    //产生a-z的ASCII码
                    result=Math.round(Math.random()*25+97);
                    sb.append(String.valueOf((char)result));
                    break;
                case 2:
                    //产生0-9的数字
                    sb.append(String.valueOf
                            (new Random().nextInt(10)));
                    break;
            }
        }
        return sb.toString();
    }

    /**
     * 生成6位的数字字符串
     * @param
     * @return
     */
    public static String createcheckCode(){
        int newNum = (int)((Math.random()*9+1)*100000);
        return String.valueOf(newNum);
    }
}

